home *** CD-ROM | disk | FTP | other *** search
- /* $Id: ddsample.c,v 1.3 1996/11/13 03:52:12 brianp Exp $ */
-
- /*
- * Mesa 3-D graphics library
- * Version: 2.0
- * Copyright (C) 1995-1996 Brian Paul
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library; if not, write to the Free
- * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
-
- /*
- * $Log: ddsample.c,v $
- * Revision 1.3 1996/11/13 03:52:12 brianp
- * updated comments
- *
- * Revision 1.2 1996/09/15 14:30:27 brianp
- * updated for new GLframebuffer and GLvisual datatypes and functions
- *
- * Revision 1.1 1996/09/13 01:38:16 brianp
- * Initial revision
- *
- */
-
-
-
- /*
- * This is a sample template for writing new Mesa device drivers.
- * You'll have to rewrite all the pseudo code below.
- *
- * Let's say you're interfacing Mesa to a window/operating system
- * called FOO. Replace all occurances of FOOMesa with the real name
- * you select for your interface (i.e. XMesa, WMesa, AmigaMesa).
- *
- * You'll have to design an API for clients to use, defined in a
- * header called Mesa/include/GL/FooMesa.h Use the sample as an
- * example. The API should at least have functions for creating
- * rendering contexts, binding rendering contexts to windows/frame
- * buffers, etc.
- *
- * Next, you'll have to write implementations for the device driver
- * functions described in dd.h
- *
- * Note that you'll usually have to flip Y coordinates since Mesa's
- * window coordinates start at the bottom and increase upward. Most
- * window system's Y-axis increases downward
- *
- * Functions marked OPTIONAL may be completely omitted by your driver.
- *
- * Your Makefile should compile this module along with the rest of
- * the core Mesa library.
- */
-
-
- #include <stdlib.h>
- #include "GL/FooMesa.h"
- #include "context.h"
- #include "types.h"
- #include "vb.h"
-
-
-
- /*
- * This struct describes the attributes (number of channels, video mode,
- * bits per pixel, etc) for a drawable (window, screen, or frame buffer).
- */
- struct foo_mesa_visual {
- GLvisual *gl_visual;
- GLboolean db_flag; /* double buffered? */
- GLboolean rgb_flag; /* RGB mode? */
- GLuint depth; /* bits per pixel (1, 8, 24, etc) */
- };
-
-
- /*
- * This struct is a wrapper for your system's notion of a window or
- * frame buffer. It's needed because most window systems don't have
- * any notion of the Z buffers, stencil buffers, etc needed by Mesa.
- */
- struct foo_mesa_buffer {
- GLframebuffer *gl_buffer; /* The depth, stencil, accum, etc buffers */
- WindowType *the_window; /* your window handle, etc */
- };
-
-
-
- /*
- * This struct contains all device-driver state information. Think of it
- * as an extension of the core GLcontext from types.h.
- */
- struct foo_mesa_context {
- GLcontext *gl_ctx; /* the core library context */
- FooMesaVisual visual;
- FooMesaBuffer buffer;
- unsigned long pixel; /* current color index or RGBA pixel value */
- unsigned long clearpixel; /* pixel for clearing the color buffers */
- /* etc... */
- };
-
-
-
-
- /**********************************************************************/
- /***** Miscellaneous device driver funcs *****/
- /**********************************************************************/
-
-
- static void finish( GLcontext *ctx )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implements glFinish if possible */
- }
-
-
-
- static void flush( GLcontext *ctx )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implements glFlush if possible */
- }
-
-
-
- static void clear_index( GLcontext *ctx, GLuint index )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* implement glClearIndex */
- /* usually just save the color index value in the foo struct */
- }
-
-
-
- static void clear_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* implement glClearColor */
- /* color components are floats in [0,1] */
- /* usually just save the value in the foo struct */
- }
-
-
-
- static void clear( GLcontext *ctx,
- GLboolean all, GLint x, GLint y, GLint width, GLint height )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /*
- * Clear the specified region of the current color buffer using the clear
- * color or index as specified by one of the two functions above.
- * If all==GL_TRUE, clear whole buffer, else just clear region defined
- * by x,y,width,height
- */
- }
-
-
-
- static void set_index( GLcontext *ctx, GLuint index )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* Set the current color index. */
- }
-
-
-
- static void set_color( GLcontext *ctx, GLubyte r, GLubyte g, GLubyte b, GLubyte a )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* Set the current RGBA color. */
- /* r is in [0,ctx->Visual->RedScale] */
- /* g is in [0,ctx->Visual->GreenScale] */
- /* b is in [0,ctx->Visual->BlueScale] */
- /* a is in [0,ctx->Visual->AlphaScale] */
- }
-
-
-
- static GLboolean index_mask( GLcontext *ctx, GLuint mask )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implement glIndexMask if possible, else
- * return GL_FALSE
- */
- }
-
-
-
- static GLboolean color_mask( GLcontext *ctx,
- GLboolean rmask, GLboolean gmask,
- GLboolean bmask, GLboolean amask)
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: implement glColorMask if possible, else
- * return GL_FALSE
- */
- }
-
-
-
- static GLboolean logicop( GLcontext *ctx, GLenum op )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /*
- * OPTIONAL FUNCTION:
- * Implements glLogicOp if possible. Return GL_TRUE if the device driver
- * can perform the operation, otherwise return GL_FALSE. If GL_FALSE
- * is returned, the logic op will be done in software by Mesa.
- */
- }
-
-
- static void dither( GLcontext *ctx, GLboolean enable )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* OPTIONAL FUNCTION: enable/disable dithering if applicable */
- }
-
-
-
- static GLboolean set_buffer( GLcontext *ctx, GLenum mode )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* set the current drawing/reading buffer, return GL_TRUE or GL_FALSE */
- /* for success/failure */
- setup_DD_pointers( ctx );
- }
-
-
-
- static void get_buffer_size( GLcontext *ctx, GLuint *width, GLuint *height )
- {
- struct foo_mesa_context *foo = (struct foo_mesa_context *) ctx->DriverCtx;
- /* return the width and height of the current buffer */
- /* if anything special has to been done when the buffer/window is */
- /* resized, do it now */
- }
-
-
-
- /**********************************************************************/
- /***** Accelerated point, line, triangle rendering *****/
- /**********************************************************************/
-
-
- /* There may several functions like this, for different screen modes, etc */
- static void fast_points_function( GLcontext *ctx, GLuint first, GLuint last )
- {
- struct vertex_buffer *VB = ctx->VB;
-
- /* Render a number of points by some hardware/OS accerated method */
- if (VB->MonoColor) {
- /* draw all points using the current color (set_color) */
- for (i=first;i<=last;i++) {
- if (VB->Unclipped[i]) {
- /* compute window coordinate */
- int x, y;
- x = (GLint) VB->Win[i][0];
- y = FLIP( (GLint) VB->Win[i][1] );
- PLOT_PIXEL( x, y, currentcolor );
- }
- }
- }
- else {
- /* each point is a different color */
- for (i=first;i<=last;i++) {
- if (VB->Unclipped[i]) {
- int x, y;
- x = (GLint) VB->Win[i][0];
- y = FLIP( (GLint) VB->Win[i][1] );
- PLOT_PIXEL( x, y, VB->Color[i] );
- }
- }
- }
- }
-
-
-
-
- /* There may several functions like this, for different screen modes, etc */
- static void fast_line_function( GLcontext *ctx, GLuint v0, GLuint v1, GLuint pv )
- {
- /* Render a line by some hardware/OS accerated method */
- struct vertex_buffer *VB = ctx->VB;
- int x0, y0, x1, y1;
- unsigned long pixel;
-
- if (VB->MonoColor) {
- pixel = current color;
- }
- else {
- pixel = VB->Color[pv];
- }
-
- x0 = (int) VB->Win[v0][0];
- y0 = FLIP( (int) VB->Win[v0][1] );
- x1 = (int) VB->Win[v1][0];
- y1 = FLIP( (int) VB->Win[v1][1] );
-
- DRAW_LINE( x0,y0, x1,y1, pixel );
- }
-
-
-
-
- /* There may several functions like this, for different screen modes, etc */
- static void fast_triangle_function( GLcontext *ctx, GLuint v0,
- GLuint v1, GLuint v2, GLuint pv )
- {
- /* Render a triangle by some hardware/OS accerated method */
- struct vertex_buffer *VB = ctx->VB;
- int i;
-
- if (VB->MonoColor) {
- pixel = current color or index;
- }
- else {
- pixel = VB->Color[pv] or VB->Index[pv];
- }
-
- DRAW_TRIANGLE( v0, v1, v2 );
- }
-
-
-
-
-
-
- /**********************************************************************/
- /***** Write spans of pixels *****/
- /**********************************************************************/
-
-
- static void write_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLuint index[],
- const GLubyte mask[] )
- {
- int i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- /* draw pixel (x[i],y[i]) using index[i] */
- }
- }
- }
-
-
-
- static void write_monoindex_span( GLcontext *ctx,
- GLuint n,GLint x,GLint y,const GLubyte mask[] )
- {
- int i;
- for (i=0;i<n;i++) {
- if (mask[i]) {
- /* draw pixel (x[i],y[i]) using current color index */
- }
- }
- }
-
-
-
- static void write_color_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte red[], const GLubyte green[],
- const GLubyte blue[], const GLubyte alpha[],
- const GLubyte mask[] )
- {
- int i;
- y=FLIP(y);
- if (mask) {
- /* draw some pixels */
- for (i=0; i<n; i++, x++) {
- if (mask[i]) {
- /* draw pixel x,y using color red[i]/green[i]/blue[i]/alpha[i] */
- }
- }
- }
- else {
- /* draw all pixels */
- for (i=0; i<n; i++, x++) {
- /* draw pixel x,y using color red[i]/green[i]/blue[i]/alpha[i] */
- }
- }
- }
-
-
-
- static void write_monocolor_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- const GLubyte mask[])
- {
- int i;
- y=FLIP(y);
- for (i=0; i<n; i++, x++) {
- if (mask[i]) {
- plot pixel (x,y) using current color
- }
- }
- }
-
-
-
- /**********************************************************************/
- /***** Read spans of pixels *****/
- /**********************************************************************/
-
-
- static void read_index_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y, GLuint index[])
- {
- int i;
- for (i=0; i<n; i++) {
- index[i] = read_pixel(x[i],y[i]);
- }
- }
-
-
-
- static void read_color_span( GLcontext *ctx,
- GLuint n, GLint x, GLint y,
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[] )
- {
- int i;
- for (i=0; i<n; i++, x++) {
- red[i] = read_red( x, y );
- green[i] = read_green( x, y );
- /* etc */
- }
- }
-
-
-
- /**********************************************************************/
- /***** Write arrays of pixels *****/
- /**********************************************************************/
-
-
- static void write_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLuint index[], const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- plot pixel x[i], y[i] using index[i]
- }
- }
- }
-
-
-
- static void write_monoindex_pixels( GLcontext *ctx,
- GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- write pixel x[i], y[i] using current index
- }
- }
- }
-
-
-
- static void write_color_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- const GLubyte r[], const GLubyte g[],
- const GLubyte b[], const GLubyte a[],
- const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- write pixel x[i], y[i] using red[i],green[i],blue[i],alpha[i]
- }
- }
- }
-
-
-
- static void write_monocolor_pixels( GLcontext *ctx,
- GLuint n,
- const GLint x[], const GLint y[],
- const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- write pixel x[i], y[i] using current color
- }
- }
- }
-
-
-
-
- /**********************************************************************/
- /***** Read arrays of pixels *****/
- /**********************************************************************/
-
- /* Read an array of color index pixels. */
- static void read_index_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLuint indx[], const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- index[i] = read_pixel( x[i], y[i] );
- }
- }
- }
-
-
-
- static void read_color_pixels( GLcontext *ctx,
- GLuint n, const GLint x[], const GLint y[],
- GLubyte red[], GLubyte green[],
- GLubyte blue[], GLubyte alpha[],
- const GLubyte mask[] )
- {
- int i;
- for (i=0; i<n; i++) {
- if (mask[i]) {
- red[i] = read_red( x[i], y[i] );
- green[i] = read_green( x[i], y[i] );
- /* etc */
- }
- }
- }
-
-
-
-
- /**********************************************************************/
- /**********************************************************************/
-
-
- static void setup_DD_pointers( GLcontext *ctx )
- {
- /* Initialize all the pointers in the DD struct. Do this whenever */
- /* a new context is made current or we change buffers via set_buffer! */
-
- ctx->Driver.UpdateState = setup_DD_pointers;
-
- ctx->Driver.ClearIndex = clear_index;
- ctx->Driver.ClearColor = clear_color;
- ctx->Driver.Clear = clear;
-
- ctx->Driver.Index = set_index;
- ctx->Driver.Color = set_color;
-
- ctx->Driver.SetBuffer = set_buffer;
- ctx->Driver.GetBufferSize = get_buffer_size;
-
- ctx->Driver.PointsFunc = fast_points_function;
- ctx->Driver.LineFunc = fast_line_function;
- ctx->Driver.TriangleFunc = fast_triangle_function;
-
- /* Pixel/span writing functions: */
- ctx->Driver.WriteColorSpan = write_color_span;
- ctx->Driver.WriteMonocolorSpan = write_monocolor_span;
- ctx->Driver.WriteColorPixels = write_color_pixels;
- ctx->Driver.WriteMonocolorPixels = write_monocolor_pixels;
- ctx->Driver.WriteIndexSpan = write_index_span;
- ctx->Driver.WriteMonoindexSpan = write_monoindex_span;
- ctx->Driver.WriteIndexPixels = write_index_pixels;
- ctx->Driver.WriteMonoindexPixels = write_monoindex_pixels;
-
- /* Pixel/span reading functions: */
- ctx->Driver.ReadIndexSpan = read_index_span;
- ctx->Driver.ReadColorSpan = read_color_span;
- ctx->Driver.ReadIndexPixels = read_index_pixels;
- ctx->Driver.ReadColorPixels = read_color_pixels;
-
-
- /*
- * OPTIONAL FUNCTIONS: these may be left uninitialized if the device
- * driver can't/needn't implement them.
- */
- #if 0
- ctx->Driver.Finish = finish;
- ctx->Driver.Flush = flush;
- ctx->Driver.IndexMask = index_mask;
- ctx->Driver.ColorMask = color_mask;
- ctx->Driver.LogicOp = logicop;
- ctx->Driver.Dither = dither;
- #endif
- }
-
-
-
- /**********************************************************************/
- /***** FOO/Mesa API Functions *****/
- /**********************************************************************/
-
-
-
- /*
- * The exact arguments to this function will depend on your window system
- */
- FooMesaVisual FooMesaCreateVisual( GLboolean rgb_mode, GLboolean db_flag,
- /* etc... */ )
- {
- FooMesaVisual v;
- GLfloat redscale, greenscale, bluescale, alphascale;
-
- v = (FooMesaVisual) calloc( 1, sizeof(struct foo_mesa_visual) );
- if (!v) {
- return NULL;
- }
-
- if (rgb_mode) {
- /* RGB(A) mode */
- redscale = ??;
- greedscale = ??;
- bluescale = ??;
- alphascale = ??;
- index_bits = 0;
- }
- else {
- /* color index mode */
- redscale = 0.0;
- greedscale = 0.0;
- bluescale = 0.0;
- alphascale = 0.0;
- index_bits = ??;
- }
-
- /* Create core visual */
- v->gl_visual = gl_create_visual( rgb_mode,
- alpha_flag,
- db_flag,
- depth_size,
- stencil_size,
- accum_size,
- redscale, greenscale,
- bluescale, alphascale,
- index_bits );
-
- return v;
- }
-
-
-
- void FooMesaDestroyVisual( FooMesaVisual v )
- {
- gl_destroy_visual( v->gl_visual );
- free( v );
- }
-
-
-
-
- FooMesaBuffer FooMesaCreateBuffer( FooMesaVisual visual,
- int /* your window id */ )
- {
- FooMesaBuffer b;
-
- b = (FooMesaBuffer) calloc( 1, sizeof(struct foo_mesa_buffer) );
- if (!b) {
- return NULL;
- }
-
- b->gl_buffer = gl_create_buffer( visual->gl_visual, windowid, 0, 0 );
-
- /* other stuff */
-
- return b;
- }
-
-
-
- void FooMesaDestroyBuffer( FooMesaBuffer b )
- {
- gl_destroy_buffer( b->gl_buffer );
- free( b );
- }
-
-
-
-
- FooMesaContext FooMesaCreateContext( FooMesaVisual visual,
- FooMesaContext share )
- {
- FooMesaContext c;
-
- c = (FooMesaContext) calloc( 1, sizeof(struct foo_mesa_context) );
- if (!c) {
- return NULL;
- }
-
- c->gl_ctx = gl_create_context( visual->gl_visual,
- share ? share->gl_ctx : NULL,
- (void *) c );
-
-
- /* you probably have to do a bunch of other initializations here. */
-
- return c;
- }
-
-
-
- void FooMesaDestroyContext( FooMesaContext c )
- {
- gl_destroy_context( c->gl_ctx );
- free( c );
- }
-
-
-
- /*
- * Make the specified context the current one */
- * Might also want to specify the window/drawable here, like for GLX.
- */
- void FooMesaMakeCurrent( FooMesaContext c, FooMesaBuffer b )
- {
- if (c && b) {
- gl_make_current( c->gl_ctx, b->gl_buffer );
- Current_context = c;
- if (c->gl_ctx->Viewport.Width==0) {
- /* initialize viewport to window size */
- gl_Viewport( c->gl_ctx, 0, 0, c->width, c->height );
- }
- }
- else {
- /* Detach */
- gl_make_current( NULL, NULL );
- Current = NULL;
- }
- }
-
-
-
- void FooMesaSwapBuffers( FooMesaBuffer b )
- {
- /* copy/swap back buffer to front if applicable */
- }
-
-
-
- /* you may need to add other FOO/Mesa functions too... */
-
-